#include <pic18fregs.h>
#include <pic16/adc.h>
#include <stdlib.h>
#include <stdio.h>
#include <usart.h>
#include "kodak_timer_master.h"

/**** Global Variables ****/
unsigned long timer_2;

command_t command;

void main(void) {
	unsigned char i;
	OSCCONbits.SCS = 0x0;		// System Clock Select bits = External oscillator
	OSCCONbits.IRCF = 0x7;		// Internal Oscillator Frequency Select bits 8 MHz (INTOSC drives clock directly)

	TRIS_ZERO_CROSS_DETECTOR_PIN = 1;
	TRIS_BACKWARD_PIN = 0;
	TRIS_FORWARD_PIN = 0;
	TRIS_LAMP_PIN  = 0;
	TRIS_DIAS_DETECTOR_PIN = 1;
	TRIS_LED = 0;

	TRIS_AD_0 = 1;
	TRIS_AD_1 = 1;

	TRIS_TX_PIN = 0;
	TRIS_RX_PIN = 1;

	BACKWARD_PIN = 0;
	FORWARD_PIN = 0;
	LAMP_PIN = 0;
	LED_PIN = 0;

	timer_2 = 0;

	// set up ad
	adc_open(2, ADC_FOSC_64, ADC_CFG_2A, ADC_FRM_RJUST | ADC_INT_OFF);

	// set up interrupt and timers
	RCONbits.IPEN = 1;

	// USART interrupt low priority
	IPR1bits.RCIP = 0;
	IPR1bits.TXIP = 0;

	// timer 2
	T2CONbits.T2CKPS0 = 1;
	T2CONbits.T2CKPS1 = 0;
	T2CONbits.TOUTPS0 = 1;
	T2CONbits.TOUTPS1 = 0;
	T2CONbits.TOUTPS2 = 0;
	T2CONbits.TOUTPS3 = 1;
	IPR1bits.TMR2IP = 0;		// low priority
	PIR1bits.TMR2IF = 1;
	T2CONbits.TMR2ON = 1;
	PIE1bits.TMR2IE = 1;

	INTCONbits.INT0IE = 0;	// zero-cross interrupt - enabled when we dimm in
													// Note: T0IE enable from Zero Cross Routine
	INTCONbits.PEIE = 1;
	INTCONbits.GIE = 1;	/* Enable Global interrupts   */	

	usart_open(	USART_TX_INT_OFF &
				USART_RX_INT_ON & 
				USART_BRGH_LOW & 
				USART_ASYNCH_MODE & 
				USART_EIGHT_BIT &
				USART_CONT_RX,
				133     // 9600 kbps
	);

//	sleep_ms(10000);
	while (1) {
		for (i = 0; i < 20; i++) {
			usart_putc(CMD_FADE_IN);
			led_debug();
			sleep_ms(600);

			usart_putc(CMD_FADE_OUT);
			led_debug();
			sleep_ms(1000);
		}
		usart_putc(CMD_NEXT);
		usart_putc(CMD_NEXT);

		sleep_ms(4500);
	}
}

void sleep_ms(unsigned long ms) {
	unsigned long start_timer_2;
	start_timer_2 = timer_2;	

// while the absolute value of the time diff < ms
	while ( (((signed long)(timer_2 - start_timer_2) < 0) ? (-1 * (timer_2 - start_timer_2)) : (timer_2 - start_timer_2)) < ms) {
		// do nothing
	}
}

static void timer_control(void) __interrupt 2 {
	if (PIR1bits.TMR2IF) {
		PR2 = TIMER2_RELOAD;		// 1 ms delay at 8 MHz
		PIR1bits.TMR2IF = 0;
		timer_2++;
	}
}

void led_debug() {
	sleep_ms(20);
	LED_PIN = 1;
	sleep_ms(80);
	LED_PIN = 0;
	sleep_ms(20);
}
